/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package id3;

import java.util.ArrayList;

/**
 *
 * @author SONY VAIO
 */
public class Utility {

    public static int ATTRIBUTE_NUM;
    public static ArrayList<AttributeDetail> attributeDetails = new ArrayList<AttributeDetail>();
    //public static ArrayList<Integer> usedAttributes_id = new ArrayList<Integer>();

    public static void PrintRecords(ArrayList<Record> records) {
        for (int i = 0; i < records.size(); ++i) {
            records.get(i).PrintRecord();
        }
    }

    public static double calculateEntropy(ArrayList<Record> data) {
        double entropy = 0;

        if (data.size() == 0) {
            return 0;
        }

        // Mendapatkan elemen kelas atribut
        AttributeDetail attributeClass = Utility.attributeDetails.get(ATTRIBUTE_NUM - 1);

        for (int i = 0; i < attributeClass.size; ++i) {
            int count = 0;
            for (int j = 0; j < data.size(); ++j) {
                Record record = data.get(j);
                String recordValue = record.getAttribute().get(Utility.ATTRIBUTE_NUM - 1).value;
                String classValue = attributeClass.list_value.get(i);

                //System.out.println(classValue + " " + recordValue + " " + data.size());
                if (recordValue.equalsIgnoreCase(classValue)) {
                    count++;
                } 
            }
            double probability = count / (double) data.size();
            if (count > 0) {
                entropy += -probability * (Math.log(probability) / Math.log(2));
            }
        }

        return entropy;
    }

    public static double calculateGain(double rootEntropy, ArrayList<Double> subEntropies, ArrayList<Integer> subSizes, int data) {
        double gain = rootEntropy;

        for (int i = 0; i < subEntropies.size(); ++i) {
            gain += -((subSizes.get(i) / (double) data) * subEntropies.get(i));
        }
        return gain;
    }

    public static boolean isAttributeUsed(int attribute_id, Node node) {
        if (node.usedAttributes_id.contains(attribute_id)) {
            return true;
        } else {
            return false;
        }
    }

    public static String getClassName(Node node) {
        String className = "";
        if (node.entropy == 0 && node.data.size() != 0) {
            className = node.data.get(0).attributes.get(ATTRIBUTE_NUM - 1).value;
        }
        return className;
    }

    public static String traverseTree(Record r, Node root){
        String result = "";

        if(root.rootName.equalsIgnoreCase(Utility.attributeDetails.get(ATTRIBUTE_NUM-1).nama)){
            result = root.className;
        }else{
            String nodeValue = "";
            for(int i = 0; i < r.attributes.size(); ++i){
                if(r.attributes.get(i).name.equalsIgnoreCase(root.rootName)){
                    nodeValue = r.attributes.get(i).value;
                    break;
                }
            }
            for(int i = 0; i < root.childrenCount; ++i){
                if(nodeValue.equalsIgnoreCase(root.children[i].arrowName)){
                    result = traverseTree(r, root.children[i]);
                }
            }
        }
        /*while(root.children != null){
            String nodeValue = "";


        }*/
        return result;
    }

    public static ArrayList<String> Inference(ArrayList<Record> records, Node node){
        ArrayList<String> hasilInference = new ArrayList<String>();
        for(int i = 0; i < records.size(); ++i){
            String hasil = Utility.traverseTree(records.get(i), node);
            hasilInference.add(hasil);
        }
        return hasilInference;
    }
}
